<html>
<head><meta charset="utf-8"><title>Trait Upcasting lang-team#98 · t-lang/major changes · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/243200-t-lang/major-changes/index.html">t-lang/major changes</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/243200-t-lang/major-changes/topic/Trait.20Upcasting.20lang-team.2398.html">Trait Upcasting lang-team#98</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="242788705"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/243200-t-lang/major%20changes/topic/Trait%20Upcasting%20lang-team%2398/near/242788705" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> triagebot <a href="https://rust-lang.github.io/zulip_archive/stream/243200-t-lang/major-changes/topic/Trait.20Upcasting.20lang-team.2398.html#242788705">(Jun 15 2021 at 19:44)</a>:</h4>
<p>A new proposal has been announced: <a href="https://github.com/rust-lang/lang-team/issues/98">Trait Upcasting #98</a>. It will be announced at the next meeting to try and draw attention to it, but usually MCPs are not discussed during triage meetings. If you think this would benefit from discussion amongst the team, consider proposing a design meeting.</p>



<a name="242790412"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/243200-t-lang/major%20changes/topic/Trait%20Upcasting%20lang-team%2398/near/242790412" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Charles Lew <a href="https://rust-lang.github.io/zulip_archive/stream/243200-t-lang/major-changes/topic/Trait.20Upcasting.20lang-team.2398.html#242790412">(Jun 15 2021 at 19:57)</a>:</h4>
<p>For background reference, there was an old topic within wg-traits stream: <a href="#narrow/stream/144729-wg-traits/topic/object.20upcasting">https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/object.20upcasting</a></p>



<a name="242790940"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/243200-t-lang/major%20changes/topic/Trait%20Upcasting%20lang-team%2398/near/242790940" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/243200-t-lang/major-changes/topic/Trait.20Upcasting.20lang-team.2398.html#242790940">(Jun 15 2021 at 20:01)</a>:</h4>
<p>This is &amp;dyn Subtrait =&gt; &amp;dyn Supertrait, where <code>trait Subtrait: Supertrait{}</code>, correct?</p>



<a name="242794208"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/243200-t-lang/major%20changes/topic/Trait%20Upcasting%20lang-team%2398/near/242794208" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/243200-t-lang/major-changes/topic/Trait.20Upcasting.20lang-team.2398.html#242794208">(Jun 15 2021 at 20:24)</a>:</h4>
<p>This is a relatively easy one since the vtable for the supertrait can be a prefix of the vtable of the subtrait, right?</p>



<a name="242797363"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/243200-t-lang/major%20changes/topic/Trait%20Upcasting%20lang-team%2398/near/242797363" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/243200-t-lang/major-changes/topic/Trait.20Upcasting.20lang-team.2398.html#242797363">(Jun 15 2021 at 20:47)</a>:</h4>
<p>It would need a vptr stored in the general case. Some cases, like single trait inheritence, should be able to use a prefix, though.</p>



<a name="242797792"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/243200-t-lang/major%20changes/topic/Trait%20Upcasting%20lang-team%2398/near/242797792" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Charles Lew <a href="https://rust-lang.github.io/zulip_archive/stream/243200-t-lang/major-changes/topic/Trait.20Upcasting.20lang-team.2398.html#242797792">(Jun 15 2021 at 20:50)</a>:</h4>
<blockquote>
<p>This is &amp;dyn Subtrait =&gt; &amp;dyn Supertrait, where trait Subtrait: Supertrait{}, correct?</p>
</blockquote>
<p>Yes!</p>



<a name="242797901"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/243200-t-lang/major%20changes/topic/Trait%20Upcasting%20lang-team%2398/near/242797901" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Charles Lew <a href="https://rust-lang.github.io/zulip_archive/stream/243200-t-lang/major-changes/topic/Trait.20Upcasting.20lang-team.2398.html#242797901">(Jun 15 2021 at 20:51)</a>:</h4>
<blockquote>
<p>This is a relatively easy one since the vtable for the supertrait can be a prefix of the vtable of the subtrait, right?</p>
</blockquote>
<p>Most but not always so. I'm planning to change the vtable structure so that supertrait vtable is always a "subslice" of the entire vtable.</p>



<a name="242798099"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/243200-t-lang/major%20changes/topic/Trait%20Upcasting%20lang-team%2398/near/242798099" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Charles Lew <a href="https://rust-lang.github.io/zulip_archive/stream/243200-t-lang/major-changes/topic/Trait.20Upcasting.20lang-team.2398.html#242798099">(Jun 15 2021 at 20:53)</a>:</h4>
<p>For multiple inheritance and diamond inheritance cases, this will mean some slots in it are duplicated.</p>



<a name="242798907"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/243200-t-lang/major%20changes/topic/Trait%20Upcasting%20lang-team%2398/near/242798907" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/243200-t-lang/major-changes/topic/Trait.20Upcasting.20lang-team.2398.html#242798907">(Jun 15 2021 at 20:59)</a>:</h4>
<p>Ah, yes, multiple supertraits.  Thanks for the reminder.</p>



<a name="242799076"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/243200-t-lang/major%20changes/topic/Trait%20Upcasting%20lang-team%2398/near/242799076" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/243200-t-lang/major-changes/topic/Trait.20Upcasting.20lang-team.2398.html#242799076">(Jun 15 2021 at 21:00)</a>:</h4>
<p>Hmm... That's a potentially reasonable setup. <br>
I considered this problem while writing an ABI for use with my (very WIP) implementation of rust, in &lt;<a href="https://github.com/LightningCreations/lccc">https://github.com/LightningCreations/lccc</a>&gt;. The method I chose was simply storing a vptr for each direct upcast trait in the vtable (and then also store the vfns in the table), <a href="https://hackmd.io/@wSaA8OrrSQ2SlegMvA6e6A/SJ1TeE0y_#DST-Pointer-Layout">https://hackmd.io/@wSaA8OrrSQ2SlegMvA6e6A/SJ1TeE0y_#DST-Pointer-Layout</a> (point 2).</p>



<a name="242799109"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/243200-t-lang/major%20changes/topic/Trait%20Upcasting%20lang-team%2398/near/242799109" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/243200-t-lang/major-changes/topic/Trait.20Upcasting.20lang-team.2398.html#242799109">(Jun 15 2021 at 21:00)</a>:</h4>
<p>Can you elaborate on "subslice"?</p>



<a name="242799442"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/243200-t-lang/major%20changes/topic/Trait%20Upcasting%20lang-team%2398/near/242799442" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/243200-t-lang/major-changes/topic/Trait.20Upcasting.20lang-team.2398.html#242799442">(Jun 15 2021 at 21:03)</a>:</h4>
<p>I think I have an idea of what is meant, so I'll attempt to explain.<br>
The layout would be a <code>struct SingleTraitVTable{...}</code>, where <code>SingleTraitVTable</code> is w/e rustc stores in the vtable for a single trait, and none of it's supertraits, and then the actual vtable would be <code>[SingleTraitVTable;N]</code> where <code>N</code> is the total number of vtables that need to be stored, such that upcasting to any trait only requires taking some subrange of that vtable.</p>



<a name="242799583"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/243200-t-lang/major%20changes/topic/Trait%20Upcasting%20lang-team%2398/near/242799583" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/243200-t-lang/major-changes/topic/Trait.20Upcasting.20lang-team.2398.html#242799583">(Jun 15 2021 at 21:04)</a>:</h4>
<p>(With potential for optimization in single inheritence cases, where it doesn't duplicate the size/alignment/drop-glue stuff where it doesn't have to)</p>



<a name="242799589"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/243200-t-lang/major%20changes/topic/Trait%20Upcasting%20lang-team%2398/near/242799589" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Charles Lew <a href="https://rust-lang.github.io/zulip_archive/stream/243200-t-lang/major-changes/topic/Trait.20Upcasting.20lang-team.2398.html#242799589">(Jun 15 2021 at 21:04)</a>:</h4>
<p>On the basis of this, we can optimize for the single inheritance case.</p>



<a name="242799592"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/243200-t-lang/major%20changes/topic/Trait%20Upcasting%20lang-team%2398/near/242799592" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Charles Lew <a href="https://rust-lang.github.io/zulip_archive/stream/243200-t-lang/major-changes/topic/Trait.20Upcasting.20lang-team.2398.html#242799592">(Jun 15 2021 at 21:04)</a>:</h4>
<p>Yeah</p>



<a name="242799650"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/243200-t-lang/major%20changes/topic/Trait%20Upcasting%20lang-team%2398/near/242799650" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Charles Lew <a href="https://rust-lang.github.io/zulip_archive/stream/243200-t-lang/major-changes/topic/Trait.20Upcasting.20lang-team.2398.html#242799650">(Jun 15 2021 at 21:04)</a>:</h4>
<div class="codehilite" data-code-language="Text only"><pre><span></span><code>    // When we create vtable, we want to ensure that each supertrait's vtable
    // is a subslice of this vtable.

    // For a single inheritance relationsihp like this,
    //   D -- C -- B -- A - DSA
    // The resulting vtable will consists of these segments:
    //  DSA, A, B, C, D

    // For a more complex inheritance relationship like this:
    //   O -- G -- C -- A - DSA
    //     \    \    \- B - DSA
    //     |    |- F -- D - DSA
    //     |         \- E - DSA
    //     |- N -- J -- H - DSA
    //          \    \- I - DSA
    //          |- M -- K - DSA
    //               \- L - DSA
    // The resulting vtable will consists of these segments:
    //  DSA, A, DSA, B, C, DSA, D, DSA E, F, G,
    //  DSA, H, DSA, I, J, DSA, K, DSA L, M, N, O
</code></pre></div>



<a name="242799728"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/243200-t-lang/major%20changes/topic/Trait%20Upcasting%20lang-team%2398/near/242799728" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Charles Lew <a href="https://rust-lang.github.io/zulip_archive/stream/243200-t-lang/major-changes/topic/Trait.20Upcasting.20lang-team.2398.html#242799728">(Jun 15 2021 at 21:05)</a>:</h4>
<p>This is some of the comments in my upcoming pr.</p>



<a name="242799744"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/243200-t-lang/major%20changes/topic/Trait%20Upcasting%20lang-team%2398/near/242799744" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Charles Lew <a href="https://rust-lang.github.io/zulip_archive/stream/243200-t-lang/major-changes/topic/Trait.20Upcasting.20lang-team.2398.html#242799744">(Jun 15 2021 at 21:05)</a>:</h4>
<p>DSA means destructor + size + alignment</p>



<a name="242799825"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/243200-t-lang/major%20changes/topic/Trait%20Upcasting%20lang-team%2398/near/242799825" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Charles Lew <a href="https://rust-lang.github.io/zulip_archive/stream/243200-t-lang/major-changes/topic/Trait.20Upcasting.20lang-team.2398.html#242799825">(Jun 15 2021 at 21:06)</a>:</h4>
<p>So for the single inheritance case, nothing is changed, it is exactly what it is today.</p>



<a name="242800169"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/243200-t-lang/major%20changes/topic/Trait%20Upcasting%20lang-team%2398/near/242800169" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Charles Lew <a href="https://rust-lang.github.io/zulip_archive/stream/243200-t-lang/major-changes/topic/Trait.20Upcasting.20lang-team.2398.html#242800169">(Jun 15 2021 at 21:09)</a>:</h4>
<p>For the multiple inheritance cases,  DSA are duplicated, so that upcasting to any trait only requires taking some subrange of that vtable. Actually for code generation we only care about the starting point. It is adding an offset to the pointer metadata.</p>



<a name="242800386"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/243200-t-lang/major%20changes/topic/Trait%20Upcasting%20lang-team%2398/near/242800386" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Charles Lew <a href="https://rust-lang.github.io/zulip_archive/stream/243200-t-lang/major-changes/topic/Trait.20Upcasting.20lang-team.2398.html#242800386">(Jun 15 2021 at 21:11)</a>:</h4>
<p>When upcasting to A, C, G, O, the offset will be 0, while upcasting to B, the offset will be 2. upcasting to D, F, the offset will be 5.</p>



<a name="242800398"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/243200-t-lang/major%20changes/topic/Trait%20Upcasting%20lang-team%2398/near/242800398" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/243200-t-lang/major-changes/topic/Trait.20Upcasting.20lang-team.2398.html#242800398">(Jun 15 2021 at 21:11)</a>:</h4>
<p>Hmmm... This actually seems like a good idea.</p>



<a name="242800402"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/243200-t-lang/major%20changes/topic/Trait%20Upcasting%20lang-team%2398/near/242800402" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Charles Lew <a href="https://rust-lang.github.io/zulip_archive/stream/243200-t-lang/major-changes/topic/Trait.20Upcasting.20lang-team.2398.html#242800402">(Jun 15 2021 at 21:11)</a>:</h4>
<p>times pointer_size ( i got the above offset numbers slightly wrong because dsa is three words, but you got the idea )</p>



<a name="242800540"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/243200-t-lang/major%20changes/topic/Trait%20Upcasting%20lang-team%2398/near/242800540" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Charles Lew <a href="https://rust-lang.github.io/zulip_archive/stream/243200-t-lang/major-changes/topic/Trait.20Upcasting.20lang-team.2398.html#242800540">(Jun 15 2021 at 21:12)</a>:</h4>
<p>I took this idea from previous discussions.</p>



<a name="242800570"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/243200-t-lang/major%20changes/topic/Trait%20Upcasting%20lang-team%2398/near/242800570" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/243200-t-lang/major-changes/topic/Trait.20Upcasting.20lang-team.2398.html#242800570">(Jun 15 2021 at 21:12)</a>:</h4>
<p>Mind if I <del>steal</del> make use of this layout. This seems a lot more efficient then storing parent vptrs in the vtable</p>



<a name="242801133"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/243200-t-lang/major%20changes/topic/Trait%20Upcasting%20lang-team%2398/near/242801133" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Charles Lew <a href="https://rust-lang.github.io/zulip_archive/stream/243200-t-lang/major-changes/topic/Trait.20Upcasting.20lang-team.2398.html#242801133">(Jun 15 2021 at 21:17)</a>:</h4>
<p>just do whatever you want with it  lol.   advices welcome!</p>



<a name="242801691"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/243200-t-lang/major%20changes/topic/Trait%20Upcasting%20lang-team%2398/near/242801691" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/243200-t-lang/major-changes/topic/Trait.20Upcasting.20lang-team.2398.html#242801691">(Jun 15 2021 at 21:22)</a>:</h4>
<p>Only potential issue: This wouldn't implementation wouldn't likely admit vtable unification. So there will likely be distinct (though equivalent) vtables for <code>&amp;T =&gt; &amp;dyn Super</code> directly, and <code>&amp;T</code> =&gt; <code>&amp;dyn Sub</code> =&gt; <code>&amp;dyn Super</code>.</p>



<a name="242804281"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/243200-t-lang/major%20changes/topic/Trait%20Upcasting%20lang-team%2398/near/242804281" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/243200-t-lang/major-changes/topic/Trait.20Upcasting.20lang-team.2398.html#242804281">(Jun 15 2021 at 21:49)</a>:</h4>
<p>Ah, got it.  Thanks!  That chart helps.</p>
<p><span class="user-mention silent" data-user-id="116458">Charles Lew</span> <a href="#narrow/stream/243200-t-lang.2Fmajor-changes/topic/Trait.20Upcasting.20lang-team.2398/near/242800169">said</a>:</p>
<blockquote>
<p>For the multiple inheritance cases,  DSA are duplicated.</p>
</blockquote>
<p>I guess today they're already duplicated per trait vtable, so this could even result in smaller overall vtable data?</p>



<a name="242817310"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/243200-t-lang/major%20changes/topic/Trait%20Upcasting%20lang-team%2398/near/242817310" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/243200-t-lang/major-changes/topic/Trait.20Upcasting.20lang-team.2398.html#242817310">(Jun 16 2021 at 00:40)</a>:</h4>
<p>If there is a lot of diamond inheritance that could result in exponential blowup of the vtable</p>



<a name="242817348"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/243200-t-lang/major%20changes/topic/Trait%20Upcasting%20lang-team%2398/near/242817348" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/243200-t-lang/major-changes/topic/Trait.20Upcasting.20lang-team.2398.html#242817348">(Jun 16 2021 at 00:40)</a>:</h4>
<p>for example, <code>trait A(n+1): Bn + Cn {}</code>, <code>trait Bn: An { fn bn(&amp;self); }</code>, <code>trait Cn: An { fn cn(&amp;self); }</code></p>



<a name="242817364"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/243200-t-lang/major%20changes/topic/Trait%20Upcasting%20lang-team%2398/near/242817364" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/243200-t-lang/major-changes/topic/Trait.20Upcasting.20lang-team.2398.html#242817364">(Jun 16 2021 at 00:41)</a>:</h4>
<p>the vtable for <code>An</code> will contain 2^n DSAs</p>



<a name="242818234"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/243200-t-lang/major%20changes/topic/Trait%20Upcasting%20lang-team%2398/near/242818234" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/243200-t-lang/major-changes/topic/Trait.20Upcasting.20lang-team.2398.html#242818234">(Jun 16 2021 at 00:54)</a>:</h4>
<p>I mean, yes, but that would be unavoidable. In the alternative, you'd have 2^n vtables, and n levels of indirection</p>



<a name="242824766"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/243200-t-lang/major%20changes/topic/Trait%20Upcasting%20lang-team%2398/near/242824766" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/243200-t-lang/major-changes/topic/Trait.20Upcasting.20lang-team.2398.html#242824766">(Jun 16 2021 at 02:55)</a>:</h4>
<p>No; if all traits have their own separate vtables then there are only 3n of them, each with size ~2n</p>



<a name="242824831"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/243200-t-lang/major%20changes/topic/Trait%20Upcasting%20lang-team%2398/near/242824831" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/243200-t-lang/major-changes/topic/Trait.20Upcasting.20lang-team.2398.html#242824831">(Jun 16 2021 at 02:56)</a>:</h4>
<p>even if you embedded all links to supertraits in the vtables that would still only be quadratic</p>



<a name="242862473"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/243200-t-lang/major%20changes/topic/Trait%20Upcasting%20lang-team%2398/near/242862473" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Charles Lew <a href="https://rust-lang.github.io/zulip_archive/stream/243200-t-lang/major-changes/topic/Trait.20Upcasting.20lang-team.2398.html#242862473">(Jun 16 2021 at 10:40)</a>:</h4>
<p><span class="user-mention" data-user-id="271719">@Mario Carneiro</span>  I'm not sure i understood your proposal. Would you mind saying more about it?</p>



<a name="242863868"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/243200-t-lang/major%20changes/topic/Trait%20Upcasting%20lang-team%2398/near/242863868" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Charles Lew <a href="https://rust-lang.github.io/zulip_archive/stream/243200-t-lang/major-changes/topic/Trait.20Upcasting.20lang-team.2398.html#242863868">(Jun 16 2021 at 10:55)</a>:</h4>
<p>Did you mean appending the supertraits vtable pointers to the existing vtable?</p>



<a name="242875962"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/243200-t-lang/major%20changes/topic/Trait%20Upcasting%20lang-team%2398/near/242875962" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/243200-t-lang/major-changes/topic/Trait.20Upcasting.20lang-team.2398.html#242875962">(Jun 16 2021 at 12:58)</a>:</h4>
<p>Suppose that the vtable for <code>An</code> is <code>bn, cn, ..., b1, c1, DST</code> and similarly for <code>Bn</code> and <code>Cn</code>. The vtables are completely unshared. There are 3n vtables, and each one has size 2n. If we need to include pointers to each supertrait vtable in the vtable An would look like <code>bn, cn, ..., b1, c1, DST, &amp;dyn Bn, &amp;dyn Cn, ..., &amp;dyn B1, &amp;dyn C1, &amp;dyn A1</code>, which is still only of size 5n, so quadratic, not exponential</p>



<a name="242876426"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/243200-t-lang/major%20changes/topic/Trait%20Upcasting%20lang-team%2398/near/242876426" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/243200-t-lang/major-changes/topic/Trait.20Upcasting.20lang-team.2398.html#242876426">(Jun 16 2021 at 13:02)</a>:</h4>
<p>Probably you want to use a hybrid of this approach and the exponential one, where some supertraits can be encoded with slices and others need a separate vtable. The ones that get slices should be a spanning tree of the supertrait DAG</p>



<a name="242876495"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/243200-t-lang/major%20changes/topic/Trait%20Upcasting%20lang-team%2398/near/242876495" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/243200-t-lang/major-changes/topic/Trait.20Upcasting.20lang-team.2398.html#242876495">(Jun 16 2021 at 13:02)</a>:</h4>
<p>...is it even a DAG? Nothing in rust ever seems to be well ordered (in the mathematical sense)</p>



<a name="242881399"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/243200-t-lang/major%20changes/topic/Trait%20Upcasting%20lang-team%2398/near/242881399" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Charles Lew <a href="https://rust-lang.github.io/zulip_archive/stream/243200-t-lang/major-changes/topic/Trait.20Upcasting.20lang-team.2398.html#242881399">(Jun 16 2021 at 13:38)</a>:</h4>
<p><span class="user-mention" data-user-id="271719">@Mario Carneiro</span>  Yes, this hybrid approach sounds good! I think i'll just give up the idea of non-zero offsets, using zero offsets as much as possible, and supply vtable pointers for all the non-zero-offset cases. It will take the advantage of both.</p>
<p>I wonder if this a little complexity is acceptable from language perspective? If it's fine i'll create a prototype implementation.</p>



<a name="242881693"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/243200-t-lang/major%20changes/topic/Trait%20Upcasting%20lang-team%2398/near/242881693" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/243200-t-lang/major-changes/topic/Trait.20Upcasting.20lang-team.2398.html#242881693">(Jun 16 2021 at 13:40)</a>:</h4>
<p>from a language perspective it's all unobservable, right? I don't think any of the vtable details are public or stable</p>



<a name="242881853"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/243200-t-lang/major%20changes/topic/Trait%20Upcasting%20lang-team%2398/near/242881853" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Charles Lew <a href="https://rust-lang.github.io/zulip_archive/stream/243200-t-lang/major-changes/topic/Trait.20Upcasting.20lang-team.2398.html#242881853">(Jun 16 2021 at 13:42)</a>:</h4>
<p>It is not observable, for now. But there was a saying something like "any implementation detail will be relied on by someone, eventually" or something.</p>



<a name="242882080"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/243200-t-lang/major%20changes/topic/Trait%20Upcasting%20lang-team%2398/near/242882080" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Charles Lew <a href="https://rust-lang.github.io/zulip_archive/stream/243200-t-lang/major-changes/topic/Trait.20Upcasting.20lang-team.2398.html#242882080">(Jun 16 2021 at 13:43)</a>:</h4>
<p>In C++ the implementation detail of vtable is already relied on by technologies like microsoft COM, etc...</p>



<a name="242885462"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/243200-t-lang/major%20changes/topic/Trait%20Upcasting%20lang-team%2398/near/242885462" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/243200-t-lang/major-changes/topic/Trait.20Upcasting.20lang-team.2398.html#242885462">(Jun 16 2021 at 14:06)</a>:</h4>
<p><span class="user-mention silent" data-user-id="116458">Charles Lew</span> <a href="#narrow/stream/243200-t-lang.2Fmajor-changes/topic/Trait.20Upcasting.20lang-team.2398/near/242882080">said</a>:</p>
<blockquote>
<p>In C++ the implementation detail of vtable is already relied on by technologies like microsoft COM, etc...</p>
</blockquote>
<p>Indeed, though those are also under the control of specific implementations. An implementation can choose to promise more than the language does, but it's never a requirement to promise something the language itself doesn't promise.</p>



<a name="243548610"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/243200-t-lang/major%20changes/topic/Trait%20Upcasting%20lang-team%2398/near/243548610" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> triagebot <a href="https://rust-lang.github.io/zulip_archive/stream/243200-t-lang/major-changes/topic/Trait.20Upcasting.20lang-team.2398.html#243548610">(Jun 22 2021 at 17:14)</a>:</h4>
<p><span class="user-group-mention" data-user-group-id="1977">@T-lang</span>: Proposal <a href="https://github.com/rust-lang/lang-team/issues/98#issuecomment-866175545">#98</a> has been seconded, and will be approved in 10 days if no objections are raised.</p>



<a name="243549228"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/243200-t-lang/major%20changes/topic/Trait%20Upcasting%20lang-team%2398/near/243549228" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/243200-t-lang/major-changes/topic/Trait.20Upcasting.20lang-team.2398.html#243549228">(Jun 22 2021 at 17:18)</a>:</h4>
<p>This presentation has some typos. (E.g. the roles of <code>Foo</code> and <code>Bar</code> switch inexplicably.)</p>
<p>More importantly, I think it would benefit from spelling out a few more cases. E.g. a trait can have multiple super-traits. I assume upcasts will be supported even in that case. </p>
<p>(I need to review the thread here; maybe I can suggest a revision to the description after doing so.)</p>



<a name="243553486"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/243200-t-lang/major%20changes/topic/Trait%20Upcasting%20lang-team%2398/near/243553486" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/243200-t-lang/major-changes/topic/Trait.20Upcasting.20lang-team.2398.html#243553486">(Jun 22 2021 at 17:48)</a>:</h4>
<p><span aria-label="+1" class="emoji emoji-1f44d" role="img" title="+1">:+1:</span></p>



<a name="243839824"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/243200-t-lang/major%20changes/topic/Trait%20Upcasting%20lang-team%2398/near/243839824" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Kimundi <a href="https://rust-lang.github.io/zulip_archive/stream/243200-t-lang/major-changes/topic/Trait.20Upcasting.20lang-team.2398.html#243839824">(Jun 24 2021 at 20:11)</a>:</h4>
<p>Just for reference, the same "exponential blowup" vs "additional pointer indirection" standoff had also been discussed in 2015: <a href="https://github.com/rust-lang/rfcs/issues/1277">https://github.com/rust-lang/rfcs/issues/1277</a></p>



<a name="243890898"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/243200-t-lang/major%20changes/topic/Trait%20Upcasting%20lang-team%2398/near/243890898" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/243200-t-lang/major-changes/topic/Trait.20Upcasting.20lang-team.2398.html#243890898">(Jun 25 2021 at 09:01)</a>:</h4>
<p>Yes...it's sort of fundamental :)</p>



<a name="244787858"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/243200-t-lang/major%20changes/topic/Trait%20Upcasting%20lang-team%2398/near/244787858" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Charles Lew <a href="https://rust-lang.github.io/zulip_archive/stream/243200-t-lang/major-changes/topic/Trait.20Upcasting.20lang-team.2398.html#244787858">(Jul 03 2021 at 07:28)</a>:</h4>
<p>The progress of this mcp is tracked in <a href="#narrow/stream/144729-wg-traits/topic/object.20upcasting">https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/object.20upcasting</a> . Made some progress recently: 2 prs merged, 1 in flight, and 1 in preparation.</p>



<a name="247130304"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/243200-t-lang/major%20changes/topic/Trait%20Upcasting%20lang-team%2398/near/247130304" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Charles Lew <a href="https://rust-lang.github.io/zulip_archive/stream/243200-t-lang/major-changes/topic/Trait.20Upcasting.20lang-team.2398.html#247130304">(Jul 25 2021 at 15:04)</a>:</h4>
<p>Recent progress after last update:<br>
1 pr merged, 1 pr ready, and 1 in preparation.</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>